package com.rerun.common.shiro.tag;

import java.io.IOException;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import freemarker.core.Environment;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * <p>Equivalent to {@link org.apache.shiro.web.tags.SecureTag}</p>
 */
public abstract class SecureTag implements TemplateDirectiveModel {
    public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
        verifyParameters(params);
        render(env, params, body);
    }

    /**
     * Render.
     *
     * @param env    the env
     * @param params the params
     * @param body   the body
     * @throws IOException       the io exception
     * @throws TemplateException the template exception
     */
    public abstract void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException;

    /**
     * Gets param.
     *
     * @param params the params
     * @param name   the name
     * @return the param
     */
    protected String getParam(Map params, String name) {
        Object value = params.get(name);

        if (value instanceof SimpleScalar) {
            return ((SimpleScalar)value).getAsString();
        }
        
        return null;
    }

    /**
     * Gets subject.
     *
     * @return the subject
     */
    protected Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    /**
     * Verify parameters.
     *
     * @param params the params
     * @throws TemplateModelException the template model exception
     */
    protected void verifyParameters(Map params) throws TemplateModelException {
    }

    /**
     * Render body.
     *
     * @param env  the env
     * @param body the body
     * @throws IOException       the io exception
     * @throws TemplateException the template exception
     */
    protected void renderBody(Environment env, TemplateDirectiveBody body) throws IOException, TemplateException {
        if (body != null) {
            body.render(env.getOut());
        }
    }
}
